package com.lenovo.spider;

import cn.hutool.core.collection.CollUtil;
import com.lenovo.spider.common.spi.ServiceScanner;
import lombok.val;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

import java.util.List;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * @author <a href="mailto:liuhan3@lenovo.com">HanL(liuhan3)</a>
 * on 2018/3/27 16:31
 */
public class SpiderEngine {
    /**
     * 爬虫集合
     */
    private final List<Spider> spiders = CollUtil.newArrayList();
    /**
     * 爬虫工作线程
     */
    private Scheduler worker = Schedulers.elastic();

    static {
        new ServiceScanner().refresh();
    }

    public static SpiderEngine get() {
        return new SpiderEngine();
    }

    /**
     * 启动所有爬虫
     */
    public void startAllSpider() {
        spiders.stream()
                .filter(Spider::isNotRunning)
                .map(Spider::getRunnable).forEach(runnable -> worker.schedule(runnable));
    }

    /**
     * 根据条件启动爬虫
     *
     * @param predicate
     */
    public void startSpider(Predicate<Spider> predicate) {
        spiders.stream()
                .filter(Spider::isNotRunning)
                .filter(predicate)
                .map(Spider::getRunnable).forEach(runnable -> worker.schedule(runnable));
    }

    /**
     * 停止所有爬虫
     */
    public void stopAllSpider() {
        spiders.stream()
                .filter(Spider::isRunning)
                .forEach(Spider::stop);
    }

    /**
     * 根据条件停止爬虫
     *
     * @param predicate
     */
    public void stopSpider(Predicate<Spider> predicate) {
        spiders.stream()
                .filter(Spider::isRunning)
                .filter(predicate)
                .forEach(Spider::stop);
    }

    public Spider createSpider(Supplier<Spider> initilize) {
        val spider = initilize.get();
        spiders.add(spider);
        return spider;
    }
}
